<?php
class BaseMongo{
    private $mongo = null;
    private $mongoDB = null;
    /**
    *构造函数，实例化mongoDB对象,$dsn可以接多个mongo的服务器，各个服务器用逗号隔开,$dsn的格式为ip:port(地址:端口号)
    */
    public function __construct($user,$pass,$dsn,$dbName){
        //$server = "mongodb://".$user.":".$pass."@".$dsn."/".$dbName;
        $server = "mongodb://".$dsn."/".$dbName;
        $this->mongo = new Mongo($server);
        $this->mongoDB=$this->mongo->$dbName;
    }
    /**
    *@param $collectionName 需要操作的集合（表）
    */
    public function getCollection($collectionName){
        return $this->mongoDB->$collectionName;
    }

    /**
     *@param $collectionName 需要操作的集合（表）
    *@param $docArr 是需要插入的文件
    *@return 插入多条记录,返回值是bool类型
    */
    public function inserts($collectionName,$docArr){
        $collection = $this->getCollection($collectionName);
        return $collection->insert($docArr);
    }
    /**
    *parameter1是需要操作的库
    *parameter2是需要操作的集合（表）
    *parameter3是更新的条件
    *parameter4是需要更新的内容
    *parameter5选项 array(justOne=>0) justOne=1时只删除1条记录
    */
    public function update($collectionName,$condition,$updateContents,$options = array(fsync=>0, upsert=>0, multiple=>0)){
        $collection = $this->getCollection($collectionName);
        $options['save'] = 1;
        return $collection->update($condition, $updateContents, $options);
    }

    /**
    *parameter2是需要操作的集合（表）
    *parameter3是删除的条件
    *parameter4选项 array(justOne=>0) justOne=1时只删除1条记录
    */
    public function delete($collectionName,$condition, $options = array(justOne=>0, fsync=>0)){
        $collection = $this->getCollection($collectionName);
        $options['save'] = 1;
        return $collection->remove($condition, $options);
    }
    /**
     * 查询MongoDB
     *parameter1是需要操作的库
     *parameter2是需要操作的集合（表）
     *parameter3 array 查询的条件array<br/>如<i>array(col_a=>111)</i>
     *parameter4 array 集合过滤器array<br/>完整的样子想这个：<i>array(sort=>array(col_a=>1,col_b=>-1), skip=>100, limit=>10, timeout=>5000, immortal=>true)</i>,这表示：
     * <ol>
     * <li>wrapped 以wrapped为封装为数组的键，默认按数组先后顺序</li>
     * <li>_id，默认不返回数据带有MongoID字段，如果指定了返回列的话也是一样的效果</li>
     * <li>sort 以col_a为ASC,col_b为DESC排序，可以多列组合</li>
     * <li>skip 表示从101条记录开始取数据，即跳过了前100条</li>
     * <li>limit 本次选取的条数</li>
     * <li>timeout 表示等待响应的时间（暂不使用）</li>
     * <li>immortal 表示是否维持链接永久有效，默认true，此时timeout失效（暂不使用）</li>
     * </ol>
     * parameter5 array 需要返回的字段（通常只返回必要的字段可以加快响应速度）
     * return  查询的结果
     */
    public function find($collectionName,$condition=array(),$result_filter=array(wrapped=>'', with_objectId=>0, timeout=>10000, immortal=>true),$ret_fields = array() ) {
        $collection = $this->getCollection($collectionName);
        $cursor = $collection->find($condition, $ret_fields);
        if ( !emptyempty($result_filter['skip'])){
            $cursor->skip($result_filter['skip']);
        }
        if ( !emptyempty($result_filter['limit'])){
            $cursor->limit($result_filter['limit']);
        }
        if ( !emptyempty($result_filter['sort'])){
            $cursor->sort($result_filter['sort']);
        }
        if ( !emptyempty($result_filter['wrapped'])){
            $wrapped = $result_filter['wrapped'];
        }
        if ( $result_filter['with_objectId']==1){ //如果指定了返回的列此项目就失效
            $with_objectId = count($ret_fields) < 1;
        }
        $result = array();
        $this->cursor = $cursor;

        if ( $wrapped == '_id'){
            while($ret = $cursor->getNext()){
                $result[$ret['_id']->{'$id'}] = $ret;
            }
        } else if (strlen ($wrapped) ) {
            while($ret=$cursor->getNext()){
                $result[$ret[$wrapped]] = $ret;
            }
        } else {
            while($ret=$cursor->getNext()){
                $result[] = $ret;
            }
        }
        if ( !$with_objectId ){
            foreach($result as $key=>$v){
                unset($result[$key]['_id']);
            }
        }
        return $result;
    }
    /**
    *parameter1是需要操作的库
    *parameter2是需要操作的集合（表）
    *parameter3查询的ID
    *parameter4返回的列，默认返回所有的列
    */
    public function findById($collectionName,$_id,$fields=array()){
        $collection = $this->getCollection($collectionName);
        return $collection->findOne(array('_id'=>( new MongoId($_id))), $fields);
    }

    /**
    * 计算集合内指定条件文档的数量
    * parameter1 string 集合名
    * parameter2 array 查询的条件
    * parameter3 int 指定返回结果数量的上限
    * parameter4 int 统计前跳过的结果数量
    * parameter5 int 集合的数量
    */
    public function count($collectionName,$condition=array(),$limit=0,$skip=0){
        $collection = $this->getCollection($collectionName);
        return $collection->count($condition, $limit, $skip);
    }

    /**
     *关闭连接
     */
    function closeConn(){
        $this->mongo->close();
    }

    /**
     *析构函数
     */
    public function __destruct() {
        $this->mongo->close();
    }
}
?>
